﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using YaAppoint.Appointments.TimeIntervals;
using YaAppoint.Response;

namespace YaAppoint.Appointments.PlanPools
{
    /// <summary>
    /// 号池计划服务
    /// </summary>
    [RemoteService(isEnabled: false)]
    public class PlanPoolAppService(IRepository<PlanPool,Guid> planPoolRepository,
                                     IRepository<TimeInterval,Guid> timeIntervalRepository,
                                     IMapper mapper) : ApplicationService, IPlanPoolAppService, ITransientDependency
    {
        private readonly IMapper _mapper = mapper;
        private readonly IRepository<PlanPool, Guid> _planPoolRepository = planPoolRepository;
        private readonly IRepository<TimeInterval, Guid> _timeIntervalRepository = timeIntervalRepository;

        /// <summary>
        /// 批量创建
        /// </summary>
        public async Task<BackJson> BatchCreate(BatchModelDto batchModel, Guid sid)
        {
            // 删除当前批量时间范围下、dayInWeek范围下的所有号池计划。
            await _planPoolRepository.DeleteAsync(x => x.ScheduleId == sid
                                                                     &&
                                                                     x.TimeInterval.StartTime >= batchModel.StartTime
                                                                     &&
                                                                     x.TimeInterval.EndTime <= batchModel.EndTime
                                                                     && batchModel.DayInWeeks.Contains(x.DayInWeek));
            // 获取批量时间范围下所有时间段

            var timeIntervals = await _timeIntervalRepository.GetListAsync(x => x.ScheduleId == sid
                                                                              &&
                                                                              x.StartTime >= batchModel.StartTime
                                                                              &&
                                                                              x.EndTime <= batchModel.EndTime
                                                                              &&
                                                                              x.IsActive);
            if (timeIntervals.Count == 0)
            {
                throw new BusinessException(CustomErrorCodes.NotTimeIntervalInRange);  
            }

            // 根据dayInWeeks 和 预约时间段 批量新建号池计划
            foreach (var dayInWeek in batchModel.DayInWeeks)
            {
                foreach (var interval in timeIntervals)
                {
                    var planPool = new PlanPool();
                    planPool.TimeInterval = interval;
                    planPool.TimeIntervalId = interval.Id;
                    planPool.AllowOverFlow = batchModel.AllowOverFlow;
                    planPool.IsActive = true;
                    planPool.MaxCount = batchModel.MaxCount;
                    planPool.OverFlowCount = 0;
                    planPool.DayInWeek = dayInWeek;
                    planPool.ScheduleId = sid;
                    
                    await _planPoolRepository.InsertAsync(planPool);
                }
            }


            return new BackJson()
            {
                code = 0,
                msg = "创建成功"
            };
        }

        /// <summary>
        /// 清空
        /// </summary>
        public async Task<BackJson> DeleteAll(Guid sid)
        {

            await _planPoolRepository.DeleteAsync(p => p.ScheduleId == sid);
            return new BackJson()
            {
                code = 0,
                msg = "已清空"
            };
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        public async Task<BackJson> DeleteMany(List<Guid> idList)
        {
            foreach (var id in idList)
            {
                await _planPoolRepository.DeleteAsync(id);
            }
            return new BackJson()
            {
                code = 0,
                msg = "批量删除成功"
            };
        }

        /// <summary>
        /// 删除单个
        /// </summary>
        public async Task<BackJson> DeletePlanPool(Guid id)
        {
            var planPool = await  _planPoolRepository.GetAsync(id);
            if(planPool!=null)
            {
                await _planPoolRepository.DeleteAsync(id);
            }

            return new BackJson()
            {
                code = 0,
                msg = "已删除"
            };
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        public async Task<BackJson> GetAsync(Guid id)
        {
            var planPool = await _planPoolRepository.GetAsync(id);
            if (planPool == null)
            {
                throw new BusinessException(CustomErrorCodes.PlanPoolNotExist);
            }
            return new BackJson()
            {
                code = 0,
                data = _mapper.Map<PlanPool, PlanPoolDto>(planPool)
            };
        }

        /// <summary>
        /// 生成排班计划表数据
        /// </summary>
        public async Task<BackJson> GetTableData(Guid sid)
        {
            var intervals = (await _timeIntervalRepository.GetListAsync(i => i.ScheduleId == sid && i.IsActive))
                             .OrderBy(t => t.StartTime).ThenBy(t => t.Order).ToList();

            return new BackJson()
            {
                code = 0,
                data = _mapper.Map<List<TimeInterval>, List<TimeIntervalDto>>(intervals)
            };
        }

        /// <summary>
        /// 提交新建
        /// </summary>
        public async Task<BackJson> SubmitCreate(CreatePlanPoolDto dto, Guid sid)
        {
             dto.ScheduleId = sid;
            var planPool = _mapper.Map<CreatePlanPoolDto, PlanPool>(dto);
            await _planPoolRepository.InsertAsync(planPool);
            return new BackJson()
            {
                code = 0,
                msg = "保存成功"
            };
        }

        /// <summary>
        /// 提交编辑
        /// </summary>
        public async Task<BackJson> SubmitEdit(PlanPoolDto dto)
        {
            var planPool = await _planPoolRepository.GetAsync(dto.Id);
            if (planPool == null)
            {
                throw new BusinessException(CustomErrorCodes.PlanPoolNotExist);
            }
            planPool.IsActive = dto.IsActive;
            planPool.MaxCount = dto.MaxCount;
            planPool.AllowOverFlow = dto.AllowOverFlow;
            planPool.OverFlowCount = dto.OverFlowCount;
            await _planPoolRepository.UpdateAsync(planPool);
            return new BackJson()
            {
                code = 0,
                msg = "保存成功"
            };
        }

        /// <summary>
        /// PlanPool组件获取号池计划详情
        /// </summary>
        public async Task<BackJson> GetTablePlanPool(Guid sid, DayInWeek weekDay, Guid intervalId)
        {
            var list = await _planPoolRepository.GetListAsync(x => x.ScheduleId == sid 
                                                                   &&
                                                                   x.DayInWeek == weekDay 
                                                                   &&
                                                                   x.TimeIntervalId == intervalId 
                                                                  );
            list = list.OrderByDescending(x => x.CreationTime).ToList();
            var res = new BackJson();
            
            if (list.Count > 0)
            {
                res.code = 0;
                res.data = new
                {
                    hasPlanPool = true,
                    planPool = _mapper.Map<PlanPool, PlanPoolDto>(list[0])
                };
            }
            else
            {
                res.code = 0;
                res.data = new
                {
                    hasPlanPool = false,
                };
            }

            return res;
        }
    }
}
